/*
-----------------------------------------------------------------------------
This source file is part of DIVA
The project of Engineering Lab, dept. of CSIE, NTNU.

Copyright (c) 2000-2006 The Software Engineering Lab, dept. of CSIE, NTNU.
-----------------------------------------------------------------------------
Filename:    MappingEngine.h
Description: This is the dummy mapping engine for testing.


-----------------------------------------------------------------------------
*/
/*------------------------------------------------------------*/
#ifndef _MappingEngine_H_
#define	_MappingEngine_H_
/*------------------------------------------------------------*/

//#include "DIVA_VM.h"
//#include "entry/WOP_Entry.h"
#include "vm_wop_pair.h"
#include <deque>
#include "xMappingTree.h"
#include "WOP_Entry.h"

using namespace std ;


class MappingEngine {
private:	
    static MappingEngine* ME;
	MappingEngine();
	void loadMDSfiles();	// added by howway
	


	
	std::vector<vm_wop_pair*>	mapping_table; /// table for keeping the relation of vm and wop entry.
	std::vector<vm_wop_pair*>   dummy_mapping_table ;

	/** the vector of wop_entry that have not been assigned VM */
	std::deque<DIVA_VM *> _newcreated ;

	/**---------------------- new data structure added for new mapping node system -------------------------------*/
	std::map<string, string> _MDStable ;
	std::vector<xMappingNode*> _all_xMappingNodes ;
	std::vector<xMappingNode*> _all_arith_xMappingNodes ;  // store all the arithmetic xMapping Nodes for efficient search for update
	std::vector<xMappingTree*> _all_xMappingTree ;//modified by hyt, 10/29/2009

	std::map<xMappingNode*, xMappingTree*> _all_node_xmt_map ;
	std::vector<pair<xMappingTree*, xMappingTree*> > _xmt_child_parent_map ;
	std::map<WOP_Entry*,xMappingTree*>  _wop_xmt_map ;  
public:
	static MappingEngine* getInstance();
	void reloadMDSfiles();	// added by howway

	/// destructor
	~MappingEngine();

	//* void add_one_link(WOP_Entry *, DIVA_VM *) { assert(false); }

	void add_wop_vm_mapping_pair(WOP_Entry *, DIVA_VM *);
	void add_wop_xmt_pair(WOP_Entry* wop, xMappingTree* xmt);
	void add_dummy_wop_link(WOP_Entry *, DIVA_VM *);
	void trigger_valueupdate() ;
	std::vector<vm_wop_pair* > * getMapping_table();
	std::vector<vm_wop_pair*>  * getDummyMapping_table();

	DIVA_VM* get_vm_by_entry(WOP_Entry* );
	DIVA_VM* get_DummyVM_from_Entry(WOP_Entry* );
	WOP_Entry* get_entry_by_vm(DIVA_VM* );
    xMappingTree* get_xmt_by_entry(WOP_Entry *en);
	std::vector<xMappingTree*>& getAllxMappingTree() { return _all_xMappingTree ; }
	void remove_xmt_fromAllxMappingTree(xMappingTree* xmt) { assert(false); }


	// void createVM(MappingTree mt) ;


	// void add_mapping_node(MappingNode *node) { _all_mapping_nodes.push_back(node); }

    //MappingNode * get_mnode_from_VM(DIVA_VM *vm);

	// std::vector<MappingNode *> * getAllNodesPtr() { return &(_all_mapping_nodes) ; }

	void addNewVM(DIVA_VM * vm) { _newcreated.push_back(vm); }

	void doLayoutForNewVM() ;	
	
	//---------------------------NEW MAPPING ENGINE HERE ------------------------------------------
	/* This method is called in Command Agent, it is used to replace createVM() */

	std::vector<xMappingNode *> * getAllxMappingNodesPtr() { return &(_all_xMappingNodes) ; }

	xMappingNode *		xSearchNodeByVM(DIVA_VM *vm);

	void				xCreateMappedObject(xMappingTree* xmt);

	void				addxMappingTree(xMappingTree* xmt);

	/** given a mapping node, this method return its parent xMappingTree it belongs to. Note that 
	    this parent xMappingTree may not be the root xMappingNode. A complicated mapping tree may
		contains composite xMappingTree that guarded by gates */
	xMappingTree *	    getParentxMappingTree(xMappingNode *m);

	/** given a mapping node, this method return the ROOT xMappingTree it belongs to 
		*/
	xMappingTree *      getRootxMappingTree(xMappingNode *m);

	std::vector<DIVA_VM*>	xGetVMbyEntry(WOP_Entry* we);

	WOP_Entry*			xGetEntrybyVM(DIVA_VM* dvm) ;

	//-------------- methods to collect entryvm pair from a mapping tree 

	void MappingEngine::sweep_to_collect_vmentry_pairs(xMappingTree* xmt);

	DIVA_VM* MappingEngine::walk_xmt_for_vm(xMappingNode *start);

	// -------------- methods to store, remove, and search pair <vartype, MDSstring> ---

	/** add a vartype of a wop entry (call wop's getVarType()) and a MDS to MappingEngine */
	void addMDString(string vartype, string MDString) ;

	/** same as above, except, en is a wop entry */
	void addMDString(WOP_Entry *en, string MDString) { addMDString(en->getVarType(), MDString) ; }

	/** Given a vartype, remove a MDS string from Mapping Engine */
	void removeMDString(string vartype);

	/** Clear all the mds string in the mapping engine */
	void clearMDString() { _MDStable.clear(); }

	/** given a vartype (wop's getVarType()), return its paired MDS. return NULL if not found */
	string searchMDString(string vartype);

	/** given a wop, this method return its paired MDS by wop's vartype. return NULL if not found */
	string searchMDString(WOP_Entry *en) { return searchMDString(en->getVarType()); }
	
	void saveToMDSfile(string filename, string vartype,string mdstring);
	 
	pair<string,string> readMDSfile(string filename) ;

	//-------------------- methods related to arithmetic mapping nodes --------------------------------
	
};
/*------------------------------------------------------------*/
#endif	//#ifndef _MappingEngine_H_
/*------------------------------------------------------------*/
